/**
 * 作者：
 * 创建时间：2012-6-28 上午9:29:48
 */
package dragon.model.fieldTemplate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import dragon.core.db.DML;
import dragon.core.exception.ExceptionHandler;
import dragon.core.io.FileHandler;
import dragon.core.io.XMLHandler;
import dragon.core.util.FilePath;
import dragon.core.util.StringUtils;
import dragon.model.base.Util;

/**
 * 字段模板模型解析
 */
public class FieldTemplateParser {

	/**
	 * 日志对象
	 */
	private static Logger logger = LoggerFactory.getLogger(FieldTemplateParser.class);

	/**
	 * 解析字段模板模型对象
	 * 
	 * @param filePath
	 *            字段模板模型xml配置文件路径
	 * @return
	 * @throws ExceptionHandler
	 */
	@SuppressWarnings("unchecked")
	public static FieldTemplate parse(String filePath) throws ExceptionHandler {

		// 构造文件路径
		if (logger.isDebugEnabled()) {
			logger.debug("获取字段模板模型，文件路径：" + filePath + " 存在：" + FileHandler.isFileExists(filePath));
		}

		// 文件不存在
		if (!FileHandler.isFileExists(filePath)) {
			return null;
		}

		// 解析文件内容，映射到对象
		List<Map<String, Object>> list = XMLHandler.readXML(filePath, "FieldTemplate", null, true);
		if (list == null || list.size() == 0) {
			return null;// 文件不是有效的模型定义文件
		}

		FieldTemplate fieldTemplate = new FieldTemplate();
		if (FilePath.MODEL_FIELDTEMPLATE.length() > filePath.lastIndexOf(FilePath.separator)) {
			fieldTemplate.setPkg("");
		} else {
			fieldTemplate.setPkg(filePath.substring(FilePath.MODEL_FIELDTEMPLATE.length(), filePath.lastIndexOf(FilePath.separator)));
		}

		// 获取FieldTemplate标签下的子级标签内容，这里默认了一个文件只存储一个模型定义(TODO:后期可改 )
		List<Map<String, Object>> children = (List<Map<String, Object>>) list.get(0).get(XMLHandler.CHILDREN_KEY);
		String tagName = null;
		String textContent = null;
		for (Map<String, Object> map : children) {
			tagName = (String) map.get(XMLHandler.TAG_NAME_KEY);
			textContent = (String) map.get(XMLHandler.TEXT_CONTENT);
			if ("type".equalsIgnoreCase(tagName)) {
				/* 字段模板类型定义 */
				fieldTemplate.setType(FieldTemplateType.valueOf(textContent));
			} else if ("dataProvider".equalsIgnoreCase(tagName)) {
				/* 数据提供者 */
				try {
					Class<IFieldTemplateDataProvider> cls = (Class<IFieldTemplateDataProvider>) Class.forName(textContent);
					fieldTemplate.setDataProvider(cls.newInstance());
				} catch (ClassNotFoundException e) {
					throw new ExceptionHandler(String.format("字段模板 %s[%s] 的数据提供者 %s 不存在。", fieldTemplate.getName(), fieldTemplate.getCode(), textContent));
				} catch (InstantiationException e) {
				} catch (IllegalAccessException e) {
				}
			} else if (!StringUtils.isEmpty(tagName)) {
				/* 基本属性 */
				Util.dynamicAssignment(fieldTemplate, tagName, textContent);
			}
		}

		/*------------------------------------------------特殊类型处理-------------------------------------------------------------------*/
		FieldTemplateType type = fieldTemplate.getType();
		if (type.equals(FieldTemplateType.CHECKBOX)) {
			fieldTemplate.setMultiple(1);// 复选框启用多选，屏蔽了用户配置参数
		} else if (type.equals(FieldTemplateType.RADIO)) {
			fieldTemplate.setMultiple(0);// 复选框启用单选，屏蔽了用户配置参数
		}

		String sql = fieldTemplate.getSql();
		if (type.equals(FieldTemplateType.CHECKBOX) || type.equals(FieldTemplateType.RADIO)) {
			// 对于CheckBox,Radio，必须提供数据源(sql 或 options 或 dataProvider)
			if (StringUtils.isEmpty(sql) && StringUtils.isEmpty(fieldTemplate.getOptions()) && fieldTemplate.getDataProvider() == null) {
				throw new ExceptionHandler(String.format("字段模板 %s[%s] 类型为 %s，缺少 sql 或 options 或 dataProvider！", fieldTemplate.getName(), fieldTemplate.getCode(), type));
			}

			// 数据源预处理，如果同时定义options，sql，dataProvider，处理优先级为：options，sql，dataProvider
			List<Map<String, Object>> optionsList = null;
			String options = fieldTemplate.getOptions();
			if (!StringUtils.isEmpty(options)) {
				String[] temps = options.split(",");
				optionsList = new ArrayList<Map<String, Object>>(temps.length);
				Map<String, Object> option = null;
				for (String temp : temps) {
					String[] kv = temp.split(":");
					if (kv.length != 2) {
						throw new ExceptionHandler(String.format("字段模板 %s[%s] 的 options 错误：%s，正确格式为：key:value,key:value,key:value...", fieldTemplate.getName(), fieldTemplate.getCode(), temp));
					}
					option = new HashMap<String, Object>();
					option.put("VALUE", kv[0]);
					option.put("TEXT", kv[1]);
					optionsList.add(option);
				}
				option = null;
				temps = null;
			} else if (!StringUtils.isEmpty(sql)) {
				// 如果提供sql，则sql语句中必须包含 value和text字段
				sql = sql.toLowerCase();
				int fromIndex = sql.indexOf("from");
				if (sql.indexOf("value") > fromIndex || sql.indexOf("text") > fromIndex) {
					throw new ExceptionHandler(String.format("字段模板 %s[%s] 的 sql 语句中必须包含 value和text字段!", fieldTemplate.getName(), fieldTemplate.getCode()));
				}
				if (fieldTemplate.getCache() == 1) {
					optionsList = DML.query(sql);
				}
			} else if (fieldTemplate.getDataProvider() != null) {
			}
			fieldTemplate.setOptionsList(optionsList);
			optionsList = null;

		} else if (type.equals(FieldTemplateType.SELECT)) {
			// 对于Select，必须提供数据源(dicRoot)
			if (fieldTemplate.getDicRoot() < 0) {
				throw new ExceptionHandler(String.format("字段模板 %s[%s] 类型为 %s，缺少 dicRoot！", fieldTemplate.getName(), fieldTemplate.getCode(), type));
			}

			// 如果提供了sql，必须对sql进行校验，sql中必须返回 id和text
			if (!StringUtils.isEmpty(sql)) {
				sql = sql.toLowerCase();
				int fromIndex = sql.indexOf("from");
				if (sql.indexOf("id") > fromIndex || sql.indexOf("text") > fromIndex) {
					throw new ExceptionHandler(String.format("字段模板 %s[%s] 的 sql 语句中必须包含 id和text字段!", fieldTemplate.getName(), fieldTemplate.getCode()));
				}
			}
		} else if (type.equals(FieldTemplateType.BDSELECTOR)) {
			// 对于BDSelector，如果配置了bizcode属性(即弹窗窗口内容来源于另一业务模型)，但没有配置url(即指定自定义页面)，则需要同时配置valuefield和textfield
			if (StringUtils.isEmpty(fieldTemplate.getUrl()) && (StringUtils.isEmpty(fieldTemplate.getTextField()) || StringUtils.isEmpty(fieldTemplate.getValueField()))) {
				throw new ExceptionHandler(String.format("字段模板 %s[%s] 类型为 %s，缺少 textField 或 valueField！", fieldTemplate.getName(), fieldTemplate.getCode(), type));
			}
		}
		type = null;
		/*------------------------------------------------特殊类型处理-------------------------------------------------------------------*/

		return fieldTemplate;
	}
}
